#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <mysql/mysql.h>
#include <errno.h>

#include "../inc/cJSON.h"
#include "../inc/tcp.h"
#include "../inc/agreement.h"
#include "../inc/login.h"

typedef struct
{
    int friend_db_id;        // 好友在 user 表的 id（整数）
    char friend_name[64];    // 好友昵称（user.name）
    char friend_userid[64];  // 好友登录账号（user.userid）
    char friend_avatar[256]; // 好友头像路径（user.user_img，默认路径兜底）
} friend_info_t;
static friend_info_t *get_friendList(client_info_p client, int *friend_count);

// 主处理函数：处理获取好友列表的命令
void handle_get_friendList_cmd(client_info_p client, cJSON *root, cJSON *response)
{

    // 检查入参有效性
    if (client == NULL || root == NULL || response == NULL)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "参数为空");
        return;
    }

    // 验证用户是否已登录
    if (client->userid <= 0)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "用户未登录");
        return;
    }

    // 解析请求中的payload
    cJSON *payload = cJSON_GetObjectItem(root, "payload");
    if (payload == NULL || payload->type != cJSON_Object)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "数据异常");
        return;
    }

    // 从payload中提取userid
    cJSON *req_userid = cJSON_GetObjectItem(payload, "userid");
    if (req_userid == NULL || req_userid->type != cJSON_String)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "数据异常");
        return;
    }

    // 验证userid与当前登录用户匹配
    if (strcmp(client->userid, req_userid->valuestring) != 0)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "身份验证失败");
        return;
    }

    // 查询好友列表
    int friend_count = 0;
    friend_info_t *friends = get_friendList(client, &friend_count);

    // 处理查询结果
    if (friend_count < 0)
    {
        // 处理查询错误
        const char *error_msg = "查询好友列表失败";
        switch (friend_count)
        {
        case -1:
            error_msg = "数据库连接失败";
            break;
        case -2:
            error_msg = "查询执行失败";
            break;
        case -3:
            error_msg = "获取结果集失败";
            break;
        case -4:
            error_msg = "内存分配失败";
            break;
        }
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", error_msg);
        return;
    }

    // 构造响应payload
    cJSON *resp_payload = cJSON_CreateObject();
    if (resp_payload == NULL)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "构造响应失败");
        free(friends);
        return;
    }

    // 添加userid到响应
    cJSON_AddStringToObject(resp_payload, "userid", req_userid->valuestring);

    // 创建好友列表数组
    cJSON *friend_list = cJSON_CreateArray();
    if (friend_list == NULL)
    {
        cJSON_AddNumberToObject(response, "code", 1);
        cJSON_AddStringToObject(response, "message", "构造好友列表失败");
        cJSON_Delete(resp_payload);
        free(friends);
        return;
    }
    
    cJSON_AddNumberToObject(response, "code", 0);
    cJSON_AddStringToObject(response, "message", "查询好友列表成功");

    // 添加好友信息到数组
    for (int i = 0; i < friend_count; i++)
    {
        cJSON *friend_item = cJSON_CreateObject();
        if (friend_item == NULL)
            continue;

        cJSON_AddNumberToObject(friend_item, "friend_db_id", friends[i].friend_db_id);
        cJSON_AddStringToObject(friend_item, "friend_name", friends[i].friend_name);
        cJSON_AddStringToObject(friend_item, "friend_userid", friends[i].friend_userid);
        cJSON_AddStringToObject(friend_item, "friend_avatar", friends[i].friend_avatar);

        cJSON_AddItemToArray(friend_list, friend_item);
    }

    // 释放好友列表内存
    free(friends);

    // 完成响应构造

    cJSON_AddItemToObject(resp_payload, "friend_list", friend_list);
    cJSON_AddItemToObject(response, "payload", resp_payload);
}

static int get_user_id_by_userid(client_info_p client, const char *userid)
{
    if (client == NULL || userid == NULL || strlen(userid) == 0)
    {
        printf("[USER] get_user_id_by_userid:入参为空\n");
        return -1;
    }

    // 检查数据库连接（适配 MYSQL * 一级指针）
    if (mysql_check_and_reconnect(&client->db_conn) != 0)
    { // 传地址：因函数要求 MYSQL **
        printf("[USER] 数据库连接失效,无法查询用户ID\n");
        return -1;
    }

    // 构造SQL：通过 userid 查 id（避免SQL注入，用 snprintf 拼接，简单场景适用）
    char sql[512] = {0};
    snprintf(sql, sizeof(sql),
             "SELECT id FROM user WHERE userid = '%s' LIMIT 1;",
             userid); // 注意：若 userid 含特殊字符需转义，此处简化处理

    // 执行SQL（直接传 MYSQL * 一级指针）
    if (mysql_query(client->db_conn, sql) != 0)
    {
        printf("[USER] 查询用户ID SQL失败：%s\n", mysql_error(client->db_conn));
        return -1;
    }

    // 获取结果集
    MYSQL_RES *result = mysql_store_result(client->db_conn);
    if (result == NULL)
    {
        printf("[USER] 获取用户ID结果集失败：%s\n", mysql_error(client->db_conn));
        return -1;
    }

    // 解析结果（只取第一行第一列）
    int user_id = -1;
    MYSQL_ROW row = mysql_fetch_row(result);
    if (row != NULL && row[0] != NULL)
    {
        user_id = atoi(row[0]); // 转成整数ID
    }

    // 释放资源
    mysql_free_result(result);
    return user_id;
}

// 查询当前用户的好友列表
static friend_info_t *get_friendList(client_info_p client, int *friend_count)
{
    if (client == NULL || friend_count == NULL)
    {
        *friend_count = 0;
        printf("[FRIEND] 入参错误:client或friend_count为空\n");
        return NULL;
    }
    *friend_count = 0; // 初始化好友数量

    // 2关键：获取当前用户的
    int curr_user_id = get_user_id_by_userid(client, client->userid);
    if (curr_user_id <= 0)
    {
        *friend_count = -1;
        printf("[FRIEND] 无法获取当前用户ID(userid:%s)\n", client->userid);
        return NULL;
    }
    printf("[FRIEND] 当前用户ID:%d(userid:%s)\n", curr_user_id, client->userid);

    if (mysql_check_and_reconnect(&client->db_conn) != 0)
    {
        *friend_count = -2;
        printf("[FRIEND] 数据库连接失效，重连失败\n");
        return NULL;
    }

    // 构造SQL（适配 friend_list 表结构：无 status、无 create_time）
    char sql[2048] = {0};
    snprintf(sql, sizeof(sql),
             "SELECT "
             "fl.friend_id AS friend_db_id, " // 直接取 friend_id（无需 CASE 判断）
             "u.name AS friend_name, "
             "u.userid AS friend_userid, "
             "IF(u.user_img IS NULL, '/static/avatar/default.png', u.user_img) AS friend_avatar "
             "FROM friend_list fl "
             "INNER JOIN `user` u ON u.id = fl.friend_id " // 直接关联 friend_id
             "WHERE fl.user_id = %d;",                     // 只查当前用户作为 user_id 的记录
             curr_user_id);

    //  执行SQL
    if (mysql_query(client->db_conn, sql) != 0)
    {
        printf("[FRIEND] 执行好友查询SQL失败:%s\n", mysql_error(client->db_conn));
        *friend_count = -3;
        return NULL;
    }

    // 获取结果集
    MYSQL_RES *result = mysql_store_result(client->db_conn);
    if (result == NULL)
    {
        printf("[FRIEND] 获取好友查询结果集失败：%s\n", mysql_error(client->db_conn));
        *friend_count = -4;
        return NULL;
    }

    // 动态数组存储好友列表
    int capacity = 4; // 初始容量
    friend_info_t *friends = (friend_info_t *)malloc(sizeof(friend_info_t) * capacity);
    if (friends == NULL)
    {
        printf("[FRIEND] 分配好友列表内存失败\n");
        mysql_free_result(result);
        *friend_count = -5;
        return NULL;
    }

    // 遍历结果集，解析好友信息
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result)) != NULL)
    {
        // 扩容检查：数量达到容量时，扩容为2倍
        if (*friend_count >= capacity)
        {
            int new_capacity = capacity * 2;
            friend_info_t *new_friends = (friend_info_t *)realloc(friends, sizeof(friend_info_t) * new_capacity);
            if (new_friends == NULL)
            {
                printf("[FRIEND] 扩容好友列表内存失败\n");
                free(friends);             // 释放旧内存
                mysql_free_result(result); // 释放结果集
                *friend_count = -5;
                return NULL;
            }
            friends = new_friends; // 更新指针为新数组
            capacity = new_capacity;
            printf("[FRIEND] 好友列表扩容成功，新容量：%d\n", capacity);
        }

        // 解析当前好友数据（按SQL字段顺序：row[0]=friend_db_id，row[1]=friend_name，row[2]=friend_userid，row[3]=friend_avatar）
        friend_info_t *curr = &friends[*friend_count];

        // 好友ID（row[0]：整数字符串转int）
        curr->friend_db_id = (row[0] != NULL) ? atoi(row[0]) : -1;

        // 好友昵称（row[1]：空则设为“未知用户”）
        if (row[1] != NULL && strlen(row[1]) > 0)
        {
            strncpy(curr->friend_name, row[1], sizeof(curr->friend_name) - 1);
        }
        else
        {
            strncpy(curr->friend_name, "未知用户", sizeof(curr->friend_name) - 1);
        }
        curr->friend_name[sizeof(curr->friend_name) - 1] = '\0'; // 确保字符串结束符

        // 好友登录账号（row[2]：空则设为空串）
        if (row[2] != NULL)
        {
            strncpy(curr->friend_userid, row[2], sizeof(curr->friend_userid) - 1);
        }
        else
        {
            curr->friend_userid[0] = '\0';
        }
        curr->friend_userid[sizeof(curr->friend_userid) - 1] = '\0';

        // 好友头像（row[3]：空则用默认路径）
        if (row[3] != NULL)
        {
            strncpy(curr->friend_avatar, row[3], sizeof(curr->friend_avatar) - 1);
        }
        else
        {
            strncpy(curr->friend_avatar, "/static/avatar/default.png", sizeof(curr->friend_avatar) - 1);
        }
        curr->friend_avatar[sizeof(curr->friend_avatar) - 1] = '\0';

        (*friend_count)++; // 好友数量+1
    }

    //  释放资源，返回结果
    mysql_free_result(result);
    // printf("[FRIEND] 好友列表查询完成，共 %d 个好友\n", *friend_count);
    return friends;
}
